package com.wzdigit.wms.wms.service.wms2sap;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.wzdigit.framework.exception.RestStatusException;
import com.wzdigit.wms.basic.domain.mid.IfPostback;
import com.wzdigit.wms.basic.domain.oqc.OqcInsp;
import com.wzdigit.wms.basic.enums.writeback.BackResultEnum;
import com.wzdigit.wms.basic.enums.writeback.TopicEnum;
import com.wzdigit.wms.wms.client.web.service.common.wms2sap.ZDT_MsgHeader;
import com.wzdigit.wms.wms.client.web.service.wms2sap.transfer.*;
import com.wzdigit.wms.common.entity.StatusCode;
import com.wzdigit.wms.wms.service.mid.IfPostbackService;
import com.wzdigit.wms.wms.strategy.webservice.iservice.ISendWebService;
import com.wzdigit.wms.wms.strategy.webservice.type.SendWebService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.StringWriter;
import java.io.Writer;
import java.rmi.RemoteException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @version 1.0
 * @desc WMS TO SAP调拨单接口
 * @Author:yangwenbiao
 * @Date 2021/2/2 3:55 PM
 */
@Slf4j
@Service
@SendWebService(value = TopicEnum.TOPIC_SAP_TRANSFER, name = "SAP调拨单接口")
public class Transfer2SapService implements ISendWebService {

    @Autowired
    IfPostbackService ifPostbackService;

    @Value("${sap.web.service.protocol-head}")
    private String protocolHead;

    @Value("${sap.web.service.transfer-url}")
    private String transferUrl;

    @Value("${wzdigit.web.service.sap.ip}")
    private String ip;


    private static final String SOURCE = "WMS";
    private static final String DESTINATION = "SAP";

    /**
     * 调SAP的【调拨单接口】
     *
     * @param oqcInsp
     * @param count
     * @return
     */
    private ZDT_007_RspRecordHead[] getReportResult(OqcInsp oqcInsp, Integer count) throws RestStatusException {
        ZDT_007_RspRecordHead[] record;
        try {

        } catch (Exception e) {
            e.printStackTrace();

            String msg = StatusCode.SAP_REPORT_CHECK_ERROR.message();
            RestStatusException exception = new RestStatusException(msg);
            exception.setContent(msg);
            throw exception;
        }
        return null;
    }

    /**
     * 定时任务调用SAP的【调拨单接口】
     *
     * @return
     */
    public ZDT_007_RspRecordHead[] report(List<ZDT_007_ReqRecordsHead> records) throws RemoteException {
        log.info("开始调用SAP调拨单接口》》》》》》》》》》》》》》》》》》》》》》》");
        //发送【向SAP调拨】的路径
        String urlString = protocolHead + ip + transferUrl;

        log.info("发送报文的路径:" + urlString);

        ZSI_007_AJ2SAP_OutProxy proxy = new ZSI_007_AJ2SAP_OutProxy();

        proxy.setEndpoint(urlString);

        log.info("ZSI_007_WMS2SAP_OutProxy:" + proxy.toString());

        // 消息头
        ZDT_MsgHeader header = new ZDT_MsgHeader();

        header.setSOURCE(SOURCE);
        header.setDESTINATION(DESTINATION);
        String dateStr = getDateStr();//日期
        header.setDATE(dateStr);
        header.setTIME(getTimeStr());
        header.setSTATUS("");
        header.setMESSAGE("");

        log.info("header:" + header);


        //输出请求的核心报文
        try {
            for (ZDT_007_ReqRecordsHead record : records) {

                //格式化生成的XML报文
                JAXBContext jc = JAXBContext.newInstance(ZDT_007_ReqRecordsHead.class);
                Marshaller ms = jc.createMarshaller();
                ms.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
                Writer writer = new StringWriter();
                ms.marshal(record, writer);

                log.info("发送报文的核心内容【xml】:" + writer.toString());
            }
        } catch (JAXBException e) {
            e.printStackTrace();
            String errMsg = "转成XML出错";
            log.error(errMsg);
            throw new RuntimeException(errMsg);
        }


        ZDT_007_Req req = new ZDT_007_Req();

        // 消息头
        req.setHeader(header);
        // 记录
        ZDT_007_ReqRecordsHead[] reqRECORDS = records.toArray(new ZDT_007_ReqRecordsHead[records.size()]);
        req.setRecords(reqRECORDS);

        ZDT_007_Rsp rsp = null;

        //调接口
        rsp = proxy.ZSI_007_AJ2SAP_Out(req);

        ZDT_007_RspRecordHead[] rspRecordArr = rsp.getRecord();


        //输出请求的核心报文
        try {
            for (ZDT_007_RspRecordHead rspRecordHead : rspRecordArr) {

                //格式化生成的XML报文
                JAXBContext jc = JAXBContext.newInstance(ZDT_007_RspRecordHead.class);
                Marshaller ms = jc.createMarshaller();
                ms.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
                Writer writer = new StringWriter();
                ms.marshal(rspRecordHead, writer);

                log.info("【调拨】返回报文的核心内容【xml】:" + writer.toString());
            }
        } catch (JAXBException e) {
            e.printStackTrace();
            String errMsg = "转成XML出错";
            log.error(errMsg);
            throw new RuntimeException(errMsg);
        }

        return rspRecordArr;
    }


    /**
     * 格式化日期，8位
     *
     * @param
     * @return
     */
    public String getDateStr() {

        Date now = new Date();

        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        String dateStr = formatter.format(now);
        return dateStr;
    }


    /**
     * 获得当前时间时分秒
     *
     * @return
     */
    private String getTimeStr() {
        Date now = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("HHmmss");
        String timeStr = formatter.format(now);
        return timeStr;
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Object send(Object object) {

        IfPostback postback = new IfPostback();

        //构造发送的数据
        IfPostback ifPostback = (IfPostback) object;
        String postbackContent = ifPostback.getPostbackContent();
        List<ZDT_007_ReqRecordsHead> reqRecordsHeadList = new ArrayList<>();
        try {
            reqRecordsHeadList = JSON.parseObject(postbackContent, new TypeReference<List<ZDT_007_ReqRecordsHead>>() {
            });
        } catch (Exception e) {
            log.error("解析成实体失败，JSON->实体");
            log.error("解析成实体失败，JSON->实体");
            log.error("解析成实体失败，JSON->实体");
            e.printStackTrace();

            postback.setIfPostbackId(ifPostback.getIfPostbackId());
            postback.setPostbackTime(new Date());
            postback.setReturnMessage("解析成实体失败，JSON->实体");
            postback.setPostbackResult(BackResultEnum.SYSTEM_ERROR_STATE.getCode());

            Integer row = ifPostbackService.updateOne(postback);

            return row;
        }


        //回参的JSON
        String returnJson = new String();
        //系统异常标识
        boolean flag = false;

        ZDT_007_RspRecordHead[] report = null;
        String error =new String();
        try {
            report = report(reqRecordsHeadList);
            //回写数据回传表
            returnJson = JSON.toJSONString(report);

        } catch (Exception e) {
            e.printStackTrace();
            log.error("调SAP调拨单接口异常");

            error=e.getMessage();
            //发生异常，更新标识
            flag = true;

        } finally {

            if (flag) {
                //调接口异常，解析异常等
                postback.setIfPostbackId(ifPostback.getIfPostbackId());
                postback.setPostbackTime(new Date());
                postback.setPostbackResult(BackResultEnum.SYSTEM_ERROR_STATE.getCode());

                postback.setReturnMessage(error);

                Integer row = ifPostbackService.updateOne(postback);
                log.info("成功更新{}条记录", row);
            } else {
                postback.setIfPostbackId(ifPostback.getIfPostbackId());
                postback.setPostbackTime(new Date());
                postback.setReturnMessage(returnJson);
                postback.setPostbackResult(BackResultEnum.BUSINESS_SUCCESS_STATE.getCode());

                for (ZDT_007_RspRecordHead head : report) {
                    if (head.getRESULT().equals("E")) {
                        postback.setPostbackResult(BackResultEnum.BUSINESS_FAIL_STATE.getCode());
                        continue;
                    }
                }

                Integer row = ifPostbackService.updateOne(postback);
                log.info("成功更新{}条记录", row);
            }
        }


        return postback;
    }
}
